package service.Impl;

import exception.BusinessException;
import model.Item;
import model.Order;
import service.IOrderRepository;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

public class SimpleOrderServiceImpl extends OrderServiceImpl {
    public SimpleOrderServiceImpl(IOrderRepository repository) {
        super(repository);
        this.items = new ArrayList<>();
    }

    private final List<Item> items; // 定义 items 变量


    @Override
    public Order createOrder(List<Item> items, boolean isVIP, LocalDateTime currentTime) {
        validateItems(items);

        List<Item> filteredItems = filterTimeSensitiveItems(items, currentTime.toLocalTime());

        double totalPrice = calculateTotalPrice(filteredItems, isVIP);

        String orderId = UUID.randomUUID().toString();
        Order order = new Order(
                orderId,
                filteredItems,
                Order.OrderStatus.CREATED,
                totalPrice,
                currentTime,
                getRemark(filteredItems, items));

        repository.save(order);
        return order;
    }

    /**
     * 验证商品列表是否符合业务规则
     */
    private void validateItems(List<Item> items) {
        if (items == null || items.isEmpty()) {
            throw new BusinessException("商品列表不能为空");
        }

        if (items.size() > 5) {
            throw new BusinessException("单笔订单最多包含5个商品项");
        }

        boolean hasMainDish = false;
        for (Item item : items) {
            if (item.getType() == Item.ItemType.DESSERT && !hasMainDish) {
                throw new BusinessException("甜品不能单独购买，必须搭配主食");
            }

            if (item.getType() == Item.ItemType.MAIN) {
                hasMainDish = true;
            }

            if (!hasMainDish) {
                throw new BusinessException("订单必须包含至少一个主食");
            }
        }
    }


    /**
     * 生成备注信息
     */
    private String getRemark(List<Item> filteredItems, List<Item> originalItems) {
        StringBuilder remarkBuilder = new StringBuilder();
        for (Item item : originalItems) {
            if (!filteredItems.contains(item)) {
                remarkBuilder.append(item.getName()).append("已下架，已为您移除该商品；");
            }
        }
        return remarkBuilder.toString();
    }

    /**
     * 过滤时间敏感商品
     */
    private List<Item> filterTimeSensitiveItems(List<Item> items, LocalTime currentTime) {
        StringBuilder remarkBuilder = new StringBuilder();
        return items.stream()
                .filter(item -> {
                    if (isTimeSensitiveItemRestricted(item, currentTime)) {
                        remarkBuilder.append(item.getName()).append("已下架，已为您移除该商品；");
                        return false;
                    }
                    return true;
                })
                .collect(Collectors.toList());
    }

    /**
     * 判断时间敏感商品是否受限
     */
    private boolean isTimeSensitiveItemRestricted(Item item, LocalTime currentTime) {
        if ("冰咖啡".equals(item.getName())) {
            return currentTime.isAfter(LocalTime.of(15, 0));
        }
        return false;
    }

    private double calculateTotalPrice(List<Item> items, boolean isVIP) {
        double totalPrice = 0.0;
        Map<String, Integer> drinkCount = new HashMap<>();

        for (Item item : items) {
            totalPrice += item.getPrice();

            if (item.getType() == Item.ItemType.DRINK) {
                drinkCount.merge(item.getName(), 1, Integer::sum);
            }
        }

        // 使用数组来封装 totalPrice，以便在方法内部修改
        double[] atomicTotalPrice = new double[]{totalPrice};

        applyBurgerAndFriesDiscount(items, atomicTotalPrice);
        applyDrinkDiscount(items, drinkCount, atomicTotalPrice);
        applyVIPDiscount(isVIP, atomicTotalPrice);

        return atomicTotalPrice[0];
    }

    /**
     * 统计订单中每种饮料的数量
     */
    private Map<String, Integer> countDrinks(List<Item> items) {
        Map<String, Integer> drinkCount = new HashMap<>();
        for (Item item : items) {
            if (item.getType() == Item.ItemType.DRINK) {
                drinkCount.merge(item.getName(), 1, Integer::sum);
            }
        }
        return drinkCount;
    }
    /**
     * 应用汉堡和薯条的折扣
     */
    private void applyBurgerAndFriesDiscount(List<Item> items, double[] totalPrice) {
        boolean hasBurger = items.stream().anyMatch(item -> "汉堡".equals(item.getName()));
        boolean hasFries = items.stream().anyMatch(item -> "薯条".equals(item.getName()));
        if (hasBurger && hasFries) {
            double burgerPrice = items.stream()
                    .filter(item -> "汉堡".equals(item.getName()))
                    .findFirst()
                    .map(Item::getPrice)
                    .orElseThrow(() -> new BusinessException("订单中没有汉堡"));
            double friesPrice = items.stream()
                    .filter(item -> "薯条".equals(item.getName()))
                    .findFirst()
                    .map(Item::getPrice)
                    .orElseThrow(() -> new BusinessException("订单中没有薯条"));
            totalPrice[0] = totalPrice[0] - burgerPrice - friesPrice + 25.0;
        }
    }

    /**
     * 应用饮料折扣
     */
    private void applyDrinkDiscount(List<Item> items, Map<String, Integer> drinkCount, double[] totalPrice) {
        for (Map.Entry<String, Integer> entry : drinkCount.entrySet()) {
            if (entry.getValue() >= 2) {
                double drinkPrice = items.stream()
                        .filter(item -> entry.getKey().equals(item.getName()))
                        .findFirst()
                        .map(Item::getPrice)
                        .orElseThrow(() -> new BusinessException("未找到饮料: " + entry.getKey()));
                int discountTimes = entry.getValue() / 2;
                totalPrice[0] -= discountTimes * 0.5 * drinkPrice;
            }
        }
    }

    /**
     * 应用VIP折扣
     */
    private void applyVIPDiscount(boolean isVIP, double[] totalPrice) {
        if (isVIP) {
            totalPrice[0] *= 0.9;
        }
    }
}